package cn.iocoder.yudao.module.alipay.service.elong.impl;

import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.*;
import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.common.ResultInfo;
import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.order.OrderDetailViewModel;
import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.pay.PaySubmitRequest;
import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.result.CreditCardValidateResult;
import cn.iocoder.yudao.module.alipay.dal.dataobject.elong.result.HotelOrderPayResult;
import cn.iocoder.yudao.module.alipay.rpc.HotelOrderPayApi;
import cn.iocoder.yudao.module.alipay.rpc.ValidateCreditCardApi;
import cn.iocoder.yudao.module.alipay.service.elong.CommonService;
import cn.iocoder.yudao.module.alipay.service.elong.OrderService;
import cn.iocoder.yudao.module.alipay.service.elong.PayService;
import cn.iocoder.yudao.module.alipay.util.AppConfigUtil;
import cn.iocoder.yudao.module.alipay.util.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PayServiceImpl implements PayService {
    @Autowired
    private ValidateCreditCardApi validateCreditCardApi;
    @Autowired
    private HotelOrderPayApi hotelOrderPayApi;
    @Autowired
    private OrderService orderservice;
    @Autowired
    private CommonService commonService;

    /**
     *
     * 提交支付信息
     *
     * @param paySubmitReq
     * @return
     */
    public ResultInfo<Boolean> submitOrderPay(PaySubmitRequest paySubmitReq){
        ResultInfo<Boolean> result = new ResultInfo<Boolean>();

        //获取订单
        OrderDetailViewModel orderDetail;
        ResultInfo<OrderDetailViewModel> orderDetailRet = orderservice.getOrderDetail(paySubmitReq.getOrderId());
        if(orderDetailRet.getIsSuccess() && orderDetailRet.getData() != null){
            orderDetail = orderDetailRet.getData();
        }else {
            result.setMsg(orderDetailRet.getMsg());
            return result;
        }
        /**
         * 订单状态判断
         * 注：若订单状态变化，则不应该提交支付请求，代理商可以引导用户去订单列表页或者订单详情页
         */
        if(commonService.isNeedPay(orderDetailRet.getData().getStatus(), orderDetailRet.getData().getShowStatus()) == false){
            result.setMsg("超时的支付，订单状态：" + EnumShowStatus.parseEnumShowStatus(orderDetailRet.getData().getShowStatus()).getDescription());
            return result;
        }

        /**
         * 订单金额确认
         * 若订单中返回的金额与请求参数中的金额不一致，则需要提示用户
         */
        if(orderDetail.getTotalPriceExchanged().equals(paySubmitReq.getAmount()) == false){
            result.setMsg("支付金额有误");
            return result;
        }

        //整理请求参数
        OrderPayCondition payCondition = new OrderPayCondition();
        payCondition.setOrderId(paySubmitReq.getOrderId());
        payCondition.setAmount(orderDetail.getTotalPriceExchanged());
        payCondition.setIsGuaranteeOrCharged(false);//默认设置为false,代理商可以根据自己的情况设置
        CreditCard cardInfo = new CreditCard();
        cardInfo.setNumber(getEncryptionCardNo(paySubmitReq.getCardNo().trim()));
        cardInfo.setHolderName(paySubmitReq.getHolderName().trim());
        cardInfo.setIdNo(paySubmitReq.getIdNo().trim());
        cardInfo.setIdType(EnumIdType.fromValue(paySubmitReq.getIdType().trim()));
        cardInfo.setExpirationYear(Integer.parseInt(paySubmitReq.getExpiration().substring(0, 4)));
        cardInfo.setExpirationMonth(Integer.parseInt(paySubmitReq.getExpiration().substring(4)));
        if(paySubmitReq.getCvv() != null && !"".equals(paySubmitReq.getCvv().trim())){
            cardInfo.setCVV(paySubmitReq.getCvv().trim());
        }
        payCondition.setCreditCard(cardInfo);

        //调用支付API
        HotelOrderPayResult payRet = hotelOrderPayApi.Invoke(payCondition);
        if("0".equals(payRet.getCode()) && payRet.getResult() != null){
            result.setIsSuccess(payRet.getResult().getIsSuccess());
            result.setMsg(payRet.getResult().getNotes());
        }else {
            System.out.println(payRet.getCode());
            result.setMsg(commonService.getErrorCode(payRet.getCode()));//此处代理商可以翻译错误码为友好提示
        }
        return result;
    }

    /**
     *
     * 验证信用卡号是否有效
     * Data属性标示是否需要提供CVV
     *
     * @param plainCardNo
     * @return
     *
     */
    public ResultInfo<Boolean> validateCreditCard(String plainCardNo){
        ResultInfo<Boolean> result = new ResultInfo<Boolean>();

        //赋值请求参数
        ValidateCreditCardCondition condition = new ValidateCreditCardCondition();
        condition.setCreditCardNo(getEncryptionCardNo(plainCardNo));
        if(condition.getCreditCardNo() == null){
            result.setMsg("信用卡加密失败");
            return result;
        }

        //调用接口
        CreditCardValidateResult validateRet = validateCreditCardApi.Invoke(condition);
        if("0".equals(validateRet.getCode()) && validateRet.getResult() != null){
            result.setIsSuccess(validateRet.getResult().isIsValid());
            result.setData(validateRet.getResult().isIsNeedVerifyCode());
            result.setMsg(validateRet.getResult().isIsValid() ? "验证通过" : "卡号不可用");
        }else {
            System.out.println(validateRet.getCode());
            result.setMsg("调用验证API失败");
        }

        return result;
    }

    /**
     *
     * 加密卡号
     *
     * @param plainCardNo
     * @return
     */
    private String getEncryptionCardNo(String plainCardNo){
        //获取加密密钥
        String appKey = AppConfigUtil.getCommonConfig("appKey");
        String key = appKey.substring(appKey.length() - 8);

        //整理加密字符串
        long epoch = System.currentTimeMillis()/1000;
        String rawString = epoch + "#" + plainCardNo;

        //加密
        String desCardNo = null;
        try {
            desCardNo = Tool.encryptDES(rawString, key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return desCardNo;
    }
}
